import Flutter
import UIKit
import StoreKit
import Security
import Foundation

@main
@objc class AppDelegate: FlutterAppDelegate {
    
    /// 跨端交互的方法通道
    var channel: FlutterMethodChannel?
    var token = ""

    private var eventSink: FlutterEventSink?
    
    override func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        
        // 注册监听来自flutter调用的处理器
        registerListenFlutterCall()
        
        
        ///EventChannel IOS 单向给Flutter 发送数据
        let controller = window?.rootViewController as! FlutterViewController
        let eventChannel = FlutterEventChannel(name: "eventChannel", binaryMessenger: controller.binaryMessenger)
        eventChannel.setStreamHandler(self)
        
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    

}



///EventChannel IOS 单向给Flutter 发送数据
extension AppDelegate : FlutterStreamHandler{
    
    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
           self.eventSink = events

           // 模拟定时发送事件
           Timer.scheduledTimer(withTimeInterval: 10.0, repeats: true) { timer in
               if let sink = self.eventSink {
                   sink("Current time: \(Date())")
               }
           }
           return nil
       }

       func onCancel(withArguments arguments: Any?) -> FlutterError? {
           self.eventSink = nil
           return nil
       }
}




// MARK: - Flutter和原生交互
private extension AppDelegate {

    /// 获取方法通道
    func methodChannel() -> FlutterMethodChannel {
        if let channel = channel  {
            return channel
        }

        let controller = window?.rootViewController as! FlutterViewController
        let channelName = "com.xs.app/flutter_native"
        channel = FlutterMethodChannel(name: channelName,
                                       binaryMessenger: controller.binaryMessenger)
        return channel!
    }

    /// 调Flutter的方法
    /// - Parameters:
    ///   - method: 方法名称
    ///   - arguments: json数据内容
    func callFlutterMethod(method: ChannelMethodEnum, arguments: String) {
        methodChannel().invokeMethod(method.toStr(), arguments: arguments)
    }

    /// 注册监听来自flutter调用的处理器
    func registerListenFlutterCall() {
        methodChannel().setMethodCallHandler { [weak self] (call, result) in
            guard let self = self else { return }
           // print("来自flutter的调用\n method: \(call.method)\n arguments: \(call.arguments)");



            let method = ChannelMethodEnum.fromStr(call.method)
            switch method {
            case .appInstallTime:
                self.handleGetAppInstallTime(call: call, result: result)
                // todo
                //self.callFlutterMethod(method: ChannelMethodEnum.notificationToken,arguments: token)
                break
            case .registerNotification:
                self.handleRegisterNotifications()
                break
            case .openAppDownload:
                guard let appId = call.arguments as? String else{return}
                let controller = window?.rootViewController as! FlutterViewController
                self.showAppStoreDialog(appId: appId, from: controller, result: result)
                break
            case .saveKeychain:
                guard let kv = call.arguments as? String else{return}
                self.saveData(kv, forKey: "com.playhive.task.app", service: "com.playhive.task.app")
                break;
            case .getKeychain:
                guard let key = call.arguments as? String else{return}
                let v = self.loadData(forKey: String(key), service: "com.playhive.task.app")
                result(v)
                break;
            default:
                result(FlutterMethodNotImplemented)
                break
            }
        }
    }

    /// 处理获取APP安装事件事件
    func handleGetAppInstallTime(call: FlutterMethodCall, result: @escaping FlutterResult) {
        var installDate: Date?
        if let urlToDocumentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
            installDate = try? FileManager.default.attributesOfItem(atPath: urlToDocumentsFolder.path)[.creationDate] as? Date
        }



//        let interval = installDate?.timeIntervalSince1970
//        var timestamp : Int = 0
//        if(interval != nil){
//            timestamp = Int(interval!)
//        }else{
//            timestamp = 0
//        }
//
//        print(timestamp)
//




        if let installTime = installDate {

//            let dateFormatter = DateFormatter()
//            dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
//            let formattedDate = dateFormatter.string(from: installTime)
//            print("安装时间")
//            print("\(formattedDate)")


            //result("\(installTime)")
            //result("\(formattedDate)")


            let interval = installDate?.timeIntervalSince1970
            var timestamp : Int = 0
            if(interval != nil){
                timestamp = Int(interval!)
            }else{
                timestamp = 0
            }

            timestamp*=1000

            result("\(timestamp)")

        } else {
            result("0")
        }
    }

    /// 处理注册消息推送事件
    func handleRegisterNotifications() {
        registerNotifications()
    }


    ///打开app下载页面
    func showAppStoreDialog(appId: String, from controller: UIViewController, result: @escaping FlutterResult) {
           let storeViewController = SKStoreProductViewController()
           storeViewController.delegate = self

           let parameters = [SKStoreProductParameterITunesItemIdentifier: appId]

        storeViewController.loadProduct(withParameters: parameters) {
               ( loaded, error) in
               if let error = error {
                   result(FlutterError(code: "LOAD_ERROR", message: "Failed to load App Store product page: \(error.localizedDescription)", details: nil))
                   return
               }
               if loaded {
                   controller.present(storeViewController, animated: true, completion: nil)
                   result(1)
               }
           }
       }


}


extension AppDelegate: SKStoreProductViewControllerDelegate {
    func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
        viewController.dismiss(animated: true, completion: nil)
    }
}



extension AppDelegate{


    // 存储数据到共享Keychain
         func saveData(_ data: String, forKey key: String, service: String) {


             let vv = loadData(forKey: key, service: service)
             if vv != nil{
                 updateData(data, forKey: key, service: service)
                 return
             }

            let keychainQuery: [String: Any] = [
                kSecClass as String: kSecClassGenericPassword,
                kSecAttrService as String: service,
                kSecAttrAccount as String: key,
                kSecValueData as String: data.data(using:.utf8)!
            ]

            let status = SecItemAdd(keychainQuery as CFDictionary, nil)
            if status == errSecSuccess {
                print("数据已成功存储到共享Keychain")
            } else {
                print("存储数据到共享Keychain出错，错误码: \(status)")
            }
        }

         // 从共享Keychain读取数据
         func loadData(forKey key: String, service: String) -> String? {
           let keychainQuery: [String: Any] = [
               kSecClass as String: kSecClassGenericPassword,
               kSecAttrService as String: service,
               kSecAttrAccount as String: key,
               kSecReturnData as String: true
           ]

           var result: AnyObject?
           let status = SecItemCopyMatching(keychainQuery as CFDictionary, &result)
           if status == errSecSuccess,
              let data = result as? Data,
              let loadedData = String(data: data, encoding:.utf8) {
               return loadedData
           } else {
               print("从共享Keychain读取数据出错，错误码: \(status)")
               return nil
           }
       }


    // 更新共享Keychain中的数据
        func updateData(_ newData: String, forKey key: String, service: String) {
            let query: [String: Any] = [
                kSecClass as String: kSecClassGenericPassword,
                kSecAttrService as String: service,
                kSecAttrAccount as String: key
            ]

            let updateAttributes: [String: Any] = [
                kSecValueData as String: newData.data(using:.utf8)!
            ]

            let status = SecItemUpdate(query as CFDictionary, updateAttributes as CFDictionary)
            if status == errSecSuccess {
                print("数据已成功更新到共享Keychain")
            } else {
                print("更新共享Keychain中的数据出错，错误码: \(status)")
            }
        }



}

// MARK: - 消息推送相关
extension AppDelegate {

    /// 注册远程消息推送
    private func registerNotifications() {
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in
            // 权限未授予
            if !granted {
                return
            }
            // 权限授予 -> 注册远程通知
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    /// 注册消息推送失败
    override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("注册远程通知失败，error: \(error)");
    }

    /// 注册消息推送成功
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // 将deviceToken传递给Flutter端
        token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("注册远程通知成功 Device Token: \(token)")

        // 发送token到Flutter端
        callFlutterMethod(method: ChannelMethodEnum.notificationToken,
                          arguments: token)
    }

    /// 当应用在前台时收到通知
    override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        print("收到消息通知: userInfo\(userInfo)")

        // 发送消息内容到Flutter端
        sendNotificationMessageToFlutter(userInfo: userInfo)

        // 这里可以选择显示通知或直接处理
        completionHandler([.alert, .sound, .badge])
    }

    /// 当用户点击通知启动或恢复应用
    override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        print("从消息通知栏启动: userInfo\(userInfo)")

        // 发送消息内容到Flutter端
        sendNotificationMessageToFlutter(userInfo: userInfo)

        completionHandler()
    }

    /// 将推送消息发送到flutter端
    /// - Parameters:
    ///   - userInfo: 消息数据
    private func sendNotificationMessageToFlutter(userInfo: [AnyHashable : Any]) {
        if let jsonData = try? JSONSerialization.data(withJSONObject: userInfo, options: []),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            // 发送消息内容到Flutter端
            callFlutterMethod(method: ChannelMethodEnum.notificationMessage,
                              arguments: jsonString)
        } else {
            print("消息转json失败")
        }
    }
}

// MARK: - 深度链/通用链开相关
extension AppDelegate {

    /// URL Scheme 触达，实现深度链接技术
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        print("APP深度链打开: url => \(url)")

        sendDeeplinkToFlutter(url: url)

        // Call the below method to send deep link to Adjust backend
      //  Adjust.appWillOpen(url)

        return true
    }

    /// Universal link 触达，通用链接实现深度链接技术
    override func application(_ application: UIApplication,  continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        print("APP通过通用链: url => \(userActivity.webpageURL?.absoluteString ?? "")")
        // 判断是否是Universal link进来的链接
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
           let webpageURL = userActivity.webpageURL {

            sendDeeplinkToFlutter(url: webpageURL)

            // Pass deep link to Adjust in order to potentially reattribute user.
          //  Adjust.appWillOpen(webpageURL)
        }
        return true
    }

    /// 将深度链发送到flutter端
    /// - Parameters:
    ///   - url: 链接
    private func sendDeeplinkToFlutter(url: URL) {
        callFlutterMethod(method: ChannelMethodEnum.deeplink,
                          arguments: url.absoluteString)
    }
}

// MARK: - 通道方法枚举
enum ChannelMethodEnum: String {
    // 调用flutter的方法
    case notificationToken = "notificationToken"
    case notificationMessage = "notificationMessage"
    case deeplink = "deeplink"



    // 来自flutter调用的方法
    case registerNotification = "registerNotification"
    case appInstallTime = "appInstallTime"
    case openAppDownload = "openAppDownload"
    case saveKeychain = "saveKeychain"
    case getKeychain = "getKeychain"


    // 未知的方法
    case unknown = "unknown"

    static func fromStr(_ methodName: String) -> ChannelMethodEnum {
        return ChannelMethodEnum(rawValue: methodName) ?? .unknown
    }

    func toStr() -> String {
        return self.rawValue
    }
}

